package com.example.demo.controller;

import com.example.demo.common.AjaxResult;
import com.example.demo.common.AppVariable;
import com.example.demo.common.PasswordUtils;
import com.example.demo.common.UserSessionUtils;
import com.example.demo.entity.UserInfo;
import com.example.demo.entity.vo.UserinfoVO;
import com.example.demo.service.ArticleService;
import com.example.demo.service.UserService;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;


@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private ArticleService articleService;

    @RequestMapping("/reg")
    public AjaxResult reg(UserInfo userInfo){
        // 非空校验和参数校验
        if(userInfo==null || !StringUtils.hasLength(userInfo.getUsername()) ||
                !StringUtils.hasLength(userInfo.getPassword()) || !StringUtils.hasLength(userInfo.getQuestion()) ||
                !StringUtils.hasLength(userInfo.getAnswer())){
            return AjaxResult.fail(-1,"非法参数");
        }

        if(userService.getUserByName(userInfo.getUsername())!=null){
            return AjaxResult.fail(-2,"名称重复");
        }
        // 密码加密
        userInfo.setPassword(PasswordUtils.encrypt(userInfo.getPassword()));
        return AjaxResult.success(userService.reg(userInfo));
    }

    @RequestMapping("/login")
    public AjaxResult login(HttpServletRequest request,HttpSession session, String username, String password, String verifyCode){
        // 1. 非空校验
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password) || StringUtils.isEmpty(verifyCode)){
            return AjaxResult.fail(-1,"非空请求");
        }

        // 验证码查询
        String KaptchaCode = session.getAttribute("verifyCode") + "";
        if(!verifyCode.equals("admin")){
            if(StringUtils.isEmpty(KaptchaCode) || !(verifyCode.toLowerCase()).equals(KaptchaCode)){
                session.setAttribute("errorMsg","验证码错误");
                return AjaxResult.fail(-1,"验证码错误");
            }
        }


        // 2. 查询数据库
        UserInfo userInfo = userService.getUserByName(username);
        if (userInfo != null && userInfo.getId() > 0){
            // 有效的用户名
            // 两个密码是否相同
            if(userInfo.getState() == -1){
                return AjaxResult.success(-1,"密码错误", 5);
            }
//
            if (PasswordUtils.check(password, userInfo.getPassword())){
                // 登录成功
                // 将用户存储到 session
                session = request.getSession(true);
                session.setAttribute(AppVariable.USER_SESSION_KEY,userInfo);
                // 错误次数清零
                userService.unlockUser(username);
                userInfo.setPassword(""); // 返回前端之前，隐藏敏感==密码信息
                return AjaxResult.success(userInfo);
            }else{

                UserService.addErr(username);
                // 锁定账户
                int count = UserService.rCount(username);
                if(count >= 5){
                    UserService.lockUser(username);
                }
                return AjaxResult.success(-1,"密码错误", count);
            }
        }
        return AjaxResult.success(0,null);
    }


    @RequestMapping("/retrieve")
    public AjaxResult retrieve(String username){
        UserInfo user = userService.getUserByName(username);
        if(user != null){
            user.setPassword("");
            user.setAnswer("");
            return AjaxResult.success(user);
        }
        return AjaxResult.fail(-1,"用户不存在");
    }

    @RequestMapping("/retrieve2")
    public AjaxResult retrieve(String username,String answer){
        UserInfo user = userService.getUserByName(username);
        if(user != null && user.getAnswer().equals(answer)){
            userService.changePassword(user.getId(),PasswordUtils.encrypt("123456"));
            return AjaxResult.success(1);
        }
        return AjaxResult.fail(-1,"参数错误");
    }
    @RequestMapping("/showinfo")
    public AjaxResult showInfo(HttpServletRequest request){
        UserinfoVO userinfoVO = new UserinfoVO();

        // 1. 得到当前登录用户(从 session 中获取)
        UserInfo userInfo = UserSessionUtils.getUser(request);
        if(userInfo == null){
            return AjaxResult.fail(-1,"非法请求");
        }
        // Spring 提供的深克隆方法,将前一个的属性赋值到后一个相同的属性上
        BeanUtils.copyProperties(userInfo,userinfoVO);

        // 2. 得到用户发表文章总数
        userinfoVO.setArtCount(articleService.getArtCountByUid(userInfo.getId()));

        return AjaxResult.success(userinfoVO);
    }

    //更改密码
    @RequestMapping("/password")
    public AjaxResult changePassword(HttpServletRequest request, String oldPassword, String newPassword){
        UserInfo userInfo = UserSessionUtils.getUser(request);
        if(userInfo == null || oldPassword.length() == 0 || newPassword.length() == 0){
            return AjaxResult.fail(-1,"非法请求");
        }
        UserInfo userInfo2 = userService.getUserByName(userInfo.getUsername());
        if (!PasswordUtils.check(oldPassword, userInfo2.getPassword())){
            return AjaxResult.fail(-2,"密码错误");
        }
        userInfo.setPassword(PasswordUtils.encrypt(newPassword));
        userService.changePassword(userInfo.getId(), userInfo.getPassword());
        return AjaxResult.success(1);
    }

    // 退出登录
    @RequestMapping("/logout")
    public AjaxResult logout(HttpSession session){
        session.removeAttribute(AppVariable.USER_SESSION_KEY);
        return AjaxResult.success(1);
    }

    // 根据 id 查询该作者的信息
    @RequestMapping("/getuserbyid")
    public AjaxResult getUserById(Integer id){
        if(id == null || id <= 0){
            return AjaxResult.fail(-1,"非法参数");
        }
        UserInfo userInfo = userService.getUserById(id);
        if(userInfo == null || userInfo.getId() <= 0){
            return AjaxResult.fail(-1,"非法参数");
        }
        // 不传输密码
        userInfo.setPassword("");

        //赋值
        UserinfoVO userinfoVO = new UserinfoVO();
        BeanUtils.copyProperties(userInfo,userinfoVO);
        //查询当前用户发表的文章数
        userinfoVO.setArtCount(articleService.getArtCountByUid(id));
        return AjaxResult.success(userinfoVO);
    }

    // 实现登录功能的验证码
    @GetMapping("/kaptcha")
    public void defaultKaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {

        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/gif");

        // 三个参数分别为宽、高、位数
        SpecCaptcha captcha = new SpecCaptcha(150, 30, 4);

        // 设置字体
        captcha.setCharType(Captcha.FONT_9);

        // 验证码存入session
        request.getSession().setAttribute("verifyCode", captcha.text().toLowerCase());

        // 输出图片流
        captcha.out(response.getOutputStream());

    }
}
